/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.formserver.vmmanager.generatacmpcode;


import com.inspur.edp.bef.component.base.GspComponent;
import com.inspur.edp.bef.component.detailcmpentity.vm.VMComponent;
import com.inspur.edp.cef.variable.dtgenerator.vardtmGenerate.javageneratecmpcode.JavaIBaseCompCodeGen;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.action.ActionParamInfo;
import com.inspur.edp.formserver.viewmodel.action.MappedCdpAction;
import com.inspur.edp.formserver.viewmodel.action.ViewModelActionInfo;
import com.inspur.edp.formserver.viewmodel.common.ViewModelActionUtil;
import com.inspur.edp.formserver.viewmodel.exception.ViewModelException;
import com.inspur.edp.formserver.vmmanager.exception.VoManagerErrorCodes;
import com.inspur.edp.formserver.vmmanager.service.VmManagerService;
import com.inspur.edp.formserver.vmmanager.util.CheckInfoUtil;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.MetadataProjectService;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

public abstract class JavaBaseCompCodeGenerator implements JavaIBaseCompCodeGen {

    ///#region 字段

    //private string compName;
    protected String nameSpace;
    private String entityNamespace;
    private GspViewModel vm;
    private String apiNamespace;
    private String path;
    protected GspMetadata metadata;
    protected ActionParamInfo info;

    public String getPath() {
        return path;
    }

    public void setPath(String value) {
        path = value;
    }

    public boolean getBelongElement() {
        return belongElement;
    }

    public void setBelongElement(boolean belongElement) {
        this.belongElement = belongElement;
    }

    private boolean belongElement;
    private RefCommonService lcmDtService;
    protected boolean isInterpretation;


    protected MappedCdpAction VMAction;

    protected RefCommonService getLcmDtService() {
        if (lcmDtService == null)
            lcmDtService = SpringBeanUtils.getBean(RefCommonService.class);
        return lcmDtService;
    }

    protected VMComponent getVmComponent() {
        ViewModelActionInfo actionInfo = ViewModelActionUtil.getActionInfo(VMAction, vm, info.getMetadata());
        GspMetadata metadata = VmManagerService.getMetadata(actionInfo, getLcmDtService());
        if (metadata == null || !(metadata.getContent() instanceof VMComponent)) {
            throw new ViewModelException(VoManagerErrorCodes.GSP_VIEWOBJECT_MANAGER_0024, null, vm.getCode(), vm.getName());
        }
        return (VMComponent) ((metadata.getContent() instanceof VMComponent) ? metadata.getContent() : null);
    }


    //protected string EntityClassName;
    //protected string ChildCode { get; private set; }

    protected abstract String getBaseClassName();

    ///#region 构造函数
    protected JavaBaseCompCodeGenerator(ActionParamInfo info, GspViewModel vm, MappedCdpAction vmAction, String nameSpace, String path) {
        this.info = info;
        this.metadata = info.getMetadata();
        this.vm = vm;
        setPath(path);
        this.VMAction = vmAction;
        this.nameSpace = VmManagerService.getComponentJavaClassName(ViewModelActionUtil.getActionInfo(vmAction, vm, info.getMetadata()));
        this.apiNamespace = vm.getApiNamespace().getDefaultNamespace();
        this.entityNamespace = vm.getMainObject().getGeneratedEntityClassInfo().getClassNamespace();
        //解析型标志
        this.isInterpretation = SpringBeanUtils.getBean(MetadataProjectService.class).isInterpretation(path);
    }

    protected abstract String getNameSpaceSuffix();

    public String getCompName() {
        if (CheckInfoUtil.checkNull(VMAction.getComponentEntityId())) {
            return getInitializeCompName();
        }

        String fullClassName = "";

        GspComponent component = getVmComponent();
        fullClassName = component.getMethod().getDotnetClassName();

        String[] sections = fullClassName.split("[.]", -1);

        return sections[sections.length - 1];
    }

    /**
     * 是否执行generateCommon()
     */
    public boolean getIsCommonGenerate() {
        return true;
    }

    public String generateCommon() {
        StringBuilder result = new StringBuilder();
        ///#region Package
        nameSpace = nameSpace.substring(0, nameSpace.lastIndexOf("."));
        result.append(JavaCompCodeNames.KeywordPackage).append(" ").append(nameSpace).append(";").append(getNewLine());
        ///#endregion
        generateUsing(result);
        result.append("\n");
        result.append(JavaCompCodeNames.KeywordPublic).append(" ").append(JavaCompCodeNames.KeywordClass).append(" ").append(getCompName()).append(" extends ").append(getBaseClassName());
        result.append(" {").append(getNewLine());
        ///#endregion
        generateField(result);
        result.append("\n");
        generateConstructor(result);

        executeCode(result);
        generateExtendMethod(result);
        ///#region ClassEnd
        result.append("}").append(getNewLine());
        return result.toString();
    }

    private String getPackageName(String componentEntityId) {
        GspMetadata metadata = getLcmDtService().getRefMetadata(componentEntityId);
        if (metadata.getContent() instanceof VMComponent) {
            return ((VMComponent) metadata.getContent()).getVmMethod().getClassName();
        } else {
            throw new ViewModelException(VoManagerErrorCodes.GSP_VIEWOBJECT_MANAGER_0025, null, componentEntityId);
        }
    }

    private void generateUsing(StringBuilder result) {
        if (!this.isInterpretation) {
            //此处不调用convertJavaImportPackage()方法,entityNamespace已经java包名
            entityNamespace = String.format("%1$s%2$s", entityNamespace, ".*");
            apiNamespace = String.format("%1$s%2$s", apiNamespace, ".*");
            result.append(getUsingStr(entityNamespace));
            result.append(getUsingStr(apiNamespace));
        }

        if (getBelongElement()) {
            result.append("import com.inspur.edp.web.help.api.LookupQueryParam;").append(getNewLine());
        }
        generateExtendUsing(result);
    }

    protected abstract void generateExtendUsing(StringBuilder result);

    protected abstract void generateConstructor(StringBuilder result);

    protected void generateExtendMethod(StringBuilder result) {

    }

    protected void generateField(StringBuilder result) {

    }

    ///#endregion


    ///#region 通用方法

    protected String getUsingStr(String value) {
        return new StringBuilder(JavaCompCodeNames.KeywordImport).append(" ").append(value).append(";").append(getNewLine()).toString();
    }


    //不加.*
    protected String getUsingStrNoStar(String value) {
        return new StringBuilder(JavaCompCodeNames.KeywordImport).append(" ").append(value).append(";").append(getNewLine()).toString();
    }

    protected String getNewLine() {
        return "\r\n";
    }

    protected String getIndentationStr() {
        return "\t";
        //return "    ";
    }

    protected String getDoubleIndentationStr() {
        return "\t\t";
    }

    protected void executeCode(StringBuilder result) {
        if (!getBelongElement()) {
            result.append(getIndentationStr()).append("@").append(JavaCompCodeNames.KeywordOverride).append(getNewLine());
            result.append(getIndentationStr()).append(JavaCompCodeNames.KeywordPublic).append(" ").append(JavaCompCodeNames.KeywordVoid).append(" ").append("execute()").append(" ").append("{").append(getNewLine());
            result.append(getIndentationStr()).append("}").append(getNewLine());
        }
        if (getBelongElement()) {
            generateBeforeHelpMethod(result);
        }
    }

    ///#endregion


    ///#region 生成Execute方法

    public String generateExecute() //这个应该用不到了
    {
        StringBuilder result = new StringBuilder();
        if (getBelongElement()) {
            result.append(getNewLine()).append(JavaCompCodeNames.HelpUsing);
            result.append("\n");
        }


        result.append(JavaCompCodeNames.KeywordPackage).append(" ").append(getNewLine()).append(nameSpace);
        result.append(getNewLine()).append("{");
        result.append(getIndentationStr()).append(JavaCompCodeNames.KeywordPublic).append(" ").append("partial").append(" ").append(JavaCompCodeNames.KeywordClass).append(" ").append(getCompName());
        result.append(getIndentationStr()).append("{").append(getNewLine());

        if (!getBelongElement()) {
            result.append(getDoubleIndentationStr()).append(JavaCompCodeNames.KeywordProtected).append(" ").append(JavaCompCodeNames.KeywordOverride).append(" ").append(JavaCompCodeNames.KeywordVoid).append(" ").append("Execute()").append(getNewLine());
            result.append(getDoubleIndentationStr()).append("{").append(getNewLine());
            result.append(getDoubleIndentationStr()).append("}").append(getNewLine());
        }
        if (getBelongElement()) {
            generateBeforeHelpMethod(result);
        }

        result.append(getIndentationStr()).append("}").append(getNewLine());

        result.append("}").append(getNewLine());

        ///#endregion

        return result.toString();
    }

    ///#endregion

    protected abstract String getInitializeCompName();

    private void generateBeforeHelpMethod(StringBuilder result) {
        result.append(getIndentationStr()).append("@").append(JavaCompCodeNames.KeywordOverride).append(getNewLine());
        result.append(getIndentationStr()).append(JavaCompCodeNames.KeywordPublic).append(getNewLine());
        result.append(getIndentationStr()).append(JavaCompCodeNames.KeywordVoid).append(" ").append("beforeHelp(LookupQueryParam lookupQueryParam)").append(" ").append("{").append(getNewLine());
        result.append(getIndentationStr()).append("}").append(getNewLine());
    }

    private void generateAfterHelpMethod(StringBuilder result) {
        result.append(getDoubleIndentationStr()).append(JavaCompCodeNames.KeywordPublic).append(" ").append(JavaCompCodeNames.KeywordOverride).append(" ").append(JavaCompCodeNames.KeywordVoid).append(" ").append("AfterHelp() ");
        result.append(getDoubleIndentationStr()).append("{").append(getNewLine());
        result.append(getDoubleIndentationStr()).append("}").append(getNewLine());
    }
}